#include <iostream>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

void Usage(const std::string &proc)
{
    std::cout << "\n\rUsage: " << proc << " serverip serverport\n"
              << std::endl;
}

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        Usage(argv[0]);
        exit(1);
    }

    std::string serveip = argv[1];
    uint16_t serveport = std::stoi(std::string(argv[2]));

    struct sockaddr_in serve;
    socklen_t serve_len = sizeof(struct sockaddr_in);
    memset(&serve, 0, serve_len);
    serve.sin_family = AF_INET;
    serve.sin_port = htons(serveport);
    inet_pton(AF_INET, serveip.c_str(), &serve.sin_addr);

    // 模拟服务器重连
    while (true)
    {
        int cnt = 5;             // 重连次数
        bool isreconnet = false; // 是否重连

        int sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0)
        {
            std::cerr << "sock fail" << std::endl;
            exit(1);
        }

        do
        {
            int ret_connet = connect(sockfd, (struct sockaddr *)&serve, serve_len);
            if (ret_connet < 0)
            {
                // std::cerr << "connet fail..." << std::endl;
                isreconnet = true;
                cnt--;
                std::cerr << "try connecting... " << cnt << std::endl;
                sleep(2);
            }
            else
            {
                // 连接成功……什么也不做
                break;
            }
        } while (cnt && isreconnet);

        if (cnt == 0) // 说明重连失败了
        {
            std::cerr << "user offonline..." << std::endl;
            exit(2);
        }

        std::string message;
        char buffer[4096] = {0};
        //while(true) //模拟客户端游戏功能
        //{
        std::cout << "Pleas enter@ ";
        std::getline(std::cin, message);

        int ret_wrt = write(sockfd, message.c_str(), message.size());
        if (ret_wrt < 0) // 说明断开连接了
        {
            std::cerr << "write error..." << std::endl;
            continue; //break;
        }
        int n = read(sockfd, buffer, sizeof(buffer));
        if (n > 0)
        {
            buffer[n] = 0;
            std::cout << buffer << std::endl;
        }
        else
        {
        //    break;
        }
        //}
        close(sockfd);
    }

    // tcp客户端也不需要手动bind，OS会自动bind
    return 0;
}